package cn.fintecher.pangolin.service.dataimp.service;

import cn.fintecher.pangolin.common.enums.*;
import cn.fintecher.pangolin.common.exception.BadRequestException;
import cn.fintecher.pangolin.common.model.DepartmentModel;
import cn.fintecher.pangolin.common.model.UploadFile;
import cn.fintecher.pangolin.common.model.UserModel;
import cn.fintecher.pangolin.common.utils.BatchNumberUtil;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.*;
import cn.fintecher.pangolin.entity.mysql.*;
import cn.fintecher.pangolin.service.dataimp.elastic.*;
import cn.fintecher.pangolin.service.dataimp.repository.*;
import cn.fintecher.pangolin.service.dataimp.request.*;
import cn.fintecher.pangolin.service.dataimp.response.FindDistributeCaseResponse;
import cn.fintecher.pangolin.service.dataimp.response.FindImportResponse;
import cn.fintecher.pangolin.service.dataimp.task.*;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.*;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.util.*;

import static cn.fintecher.pangolin.common.enums.ImportDataExcelStatus.REVOKING;

/**
 * @Auther: xiaqun
 * @Description:
 * @Date: 16:29 2019/8/26
 */

@Service("dataImportService")
@Transactional(rollbackFor = Exception.class)
public class DataImportService {
    @Autowired
    private BaseService baseService;

    @Autowired
    private DataImportRecordElastic dataImportRecordElastic;

    @Autowired
    private ImportTemplateElastic importTemplateElastic;

    @Autowired
    private PrincipalRepository principalRepository;

    @Autowired
    private ImportCaseTask importCaseTask;

    @Autowired
    private ConfirmCaseTask confirmCaseTask;

    @Autowired
    private PersonalImportModelElastic personalImportModelElastic;

    @Autowired
    private ModelMapper modelMapper;

    @Autowired
    private BaseCaseElastic baseCaseElastic;

    @Autowired
    private ImportCaseUpdateTask importCaseUpdateTask;

    @Autowired
    private ConfirmUpdateCaseTask confirmUpdateCaseTask;

    @Autowired
    private SysParamRepository sysParamRepository;

    @Autowired
    private ImportCommonTask importCommonTask;

    @Autowired
    private PaymentRecordModelElastic paymentRecordModelElastic;

    @Autowired
    private ConfirmBillTask confirmBillTask;

    @Autowired
    private PreRecordModelElastic preRecordModelElastic;

    @Autowired
    private ConfirmPreRecordTask confirmPreRecordTask;

    @Autowired
    private WorkOrderModelElastic workOrderModelElastic;

    @Autowired
    private WarningModelElastic warningModelElastic;

    @Autowired
    private ConfirmWorkOrderTask confirmWorkOrderTask;

    @Autowired
    private ConfirmWarningTask confirmWarningTask;

    @Autowired
    private LeaveCaseModelElastic leaveCaseModelElastic;

    @Autowired
    private StopCaseModelElastic stopCaseModelElastic;

    @Autowired
    private ConfirmLeaveTask confirmLeaveTask;

    @Autowired
    private ConfirmStopTask confirmStopTask;

    @Autowired
    private ImportDistributeTask importDistributeTask;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private DistributeImportRecordElastic distributeImportRecordElastic;

    @Autowired
    private DistributeModelElastic distributeModelElastic;

    @Autowired
    private ConfirmDistributeTask confirmDistributeTask;

    @Autowired
    private CancelPreTask cancelPreTask;

    @Autowired
    private CancelWorkOrderTask cancelWorkOrderTask;

    @Autowired
    private CancelWarningTask cancelWarningTask;

    @Autowired
    private CancelLeaveTask cancelLeaveTask;

    @Autowired
    private CancelStopTask cancelStopTask;

    @Autowired
    private CancelBillTask cancelBillTask;

    @Autowired
    private HistoryCasesRepository historyCasesRepository;

    /**
     * 导入案件查询
     */
    public Page<DataImportRecord> findAllDataImportResult(FindDataImportRequest request, Pageable pageable, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        BoolQueryBuilder builder = request.getBuilder();
        baseService.spliceBuilder(builder, userModel);
        FieldSortBuilder sort = SortBuilders.fieldSort("operateTime").unmappedType("long").order(SortOrder.DESC);
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).withSort(sort).build();
        return dataImportRecordElastic.search(searchQuery);
    }

    /**
     * 案件导入
     */
    public void importCase(ImportCaseRequest request, String token, ImportTemplateType type) {
        UserModel userModel = baseService.getUserByToken(token);
        ImportTemplate importTemplate = importTemplateElastic.findById(request.getTemplateId()).orElseThrow(() -> new BadRequestException(null, "template", "template.is.null"));
        Principal principal = principalRepository.findById(request.getPrincipalId()).orElseThrow(() -> new BadRequestException(null, "principal", "principal.is.null"));
        InputStream inputStream = baseService.getFile(request.getFileId());
        //生成导入结果
        Object o = principalRepository.getBatchNumber();
        String batchNumber = BatchNumberUtil.getBatchNumber(o.toString());
        DataImportRecord result;
        //异步执行案件导入
        switch (type) {
            case CASE_IMPORT:
                result = generateRecord(userModel, batchNumber, principal.getId(), principal.getName(), ImportTemplateType.CASE_IMPORT);
                importCaseTask.importCase(inputStream, importTemplate, batchNumber, result, request, userModel);
                break;
            case CASE_UPDATE:
                result = generateRecord(userModel, batchNumber, principal.getId(), principal.getName(), ImportTemplateType.CASE_UPDATE);
                importCaseUpdateTask.updateCase(inputStream, importTemplate, result, batchNumber, userModel);
                break;
            default:
                break;
        }
    }

    /**
     * 取消导入
     */
    public void cancelImport(String id, String token, ImportTemplateType type) {
        UserModel userModel = baseService.getUserByToken(token);
        DataImportRecord record = processRecord(userModel, id, ImportDataExcelStatus.IMPORT_CANCEL);
        //删除导入数据
        switch (type) {
            case CASE_IMPORT:
            case CASE_UPDATE:
                Iterable<PersonalImportModel> importModels = getPersonalImportModel(record.getBatchNumber());
                importModels.forEach(e -> e.setFlag(1));
                personalImportModelElastic.saveAll(importModels);
                break;
            case BILL_IMPORT:
                Iterable<PaymentRecordModel> models = getPaymentRecordModel(record.getBatchNumber());
                models.forEach(e -> e.setFlag(1));
                paymentRecordModelElastic.saveAll(models);
                break;
            case PRE_RECORD_IMPORT:
                Iterable<PreRecordModel> preRecordModels = getPreRecordModel(record.getBatchNumber());
                preRecordModels.forEach(e -> e.setFlag(1));
                preRecordModelElastic.saveAll(preRecordModels);
                break;
            case WORK_ORDER_IMPORT:
                Iterable<WorkOrderModel> workOrderModels = getWorkOrder(record.getBatchNumber());
                workOrderModels.forEach(e -> e.setFlag(1));
                workOrderModelElastic.saveAll(workOrderModels);
                break;
            case WARNING_IMPORT:
                Iterable<WarningModel> warningModels = getWarning(record.getBatchNumber());
                warningModels.forEach(e -> e.setFlag(1));
                warningModelElastic.saveAll(warningModels);
                break;
            case LEAVE_IMPORT:
                Iterable<LeaveCaseModel> leaveCaseModels = getLeave(record.getBatchNumber());
                leaveCaseModels.forEach(e -> e.setFlag(1));
                leaveCaseModelElastic.saveAll(leaveCaseModels);
                break;
            case STOP_IMPORT:
                Iterable<StopCaseModel> stopCaseModels = getStop(record.getBatchNumber());
                stopCaseModels.forEach(e -> e.setFlag(1));
                stopCaseModelElastic.saveAll(stopCaseModels);
                break;
            default:
                break;
        }
    }

    /**
     * 导入详情查询
     */
    public Page<FindImportResponse> findImportByBatchNumber(FindImportRequest request, Pageable pageable) {
        BoolQueryBuilder builder = request.getBuilder();
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).build();
        Page<PersonalImportModel> page = personalImportModelElastic.search(searchQuery);
        return page.map(e -> modelMapper.map(e, FindImportResponse.class));
    }

    /**
     * 案件确认
     */
    public void confirmCase(String id, String token, ImportTemplateType type) {
        UserModel userModel = baseService.getUserByToken(token);
        DataImportRecord record = processRecord(userModel, id, ImportDataExcelStatus.IMPORT_CONFIRMING);
        //异步执行案件确认
        switch (type) {
            case CASE_IMPORT:
                confirmCaseTask.confirm(userModel, record);
                break;
            case CASE_UPDATE:
                confirmUpdateCaseTask.confirm(userModel, record);
                break;
            default:
                break;
        }
    }

    /**
     * 处理案件导入结果
     */
    private DataImportRecord processRecord(UserModel userModel, String id, ImportDataExcelStatus status) {
        DataImportRecord record = dataImportRecordElastic.findById(id).orElseThrow(() -> new BadRequestException(null, "dataImportRecord", "dataImportRecord.is.null"));
        record.setStatus(status); //导入确认中
        record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
        return dataImportRecordElastic.save(record);
    }

    /**
     * 获取分案导入详情
     */
    private Iterable<PersonalImportModel> getPersonalImportModel(String batchNumber) {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", batchNumber));
        return personalImportModelElastic.search(builder);
    }

    /**
     * 获取对账单导入详情
     */
    private Iterable<PaymentRecordModel> getPaymentRecordModel(String batchNumber) {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", batchNumber));
        return paymentRecordModelElastic.search(builder);
    }

    /**
     * 获取委前催记导入详情
     */
    private Iterable<PreRecordModel> getPreRecordModel(String batchNumber) {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", batchNumber));
        return preRecordModelElastic.search(builder);
    }

    /**
     * 获取工单导入详情
     */
    private Iterable<WorkOrderModel> getWorkOrder(String batchNumber) {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", batchNumber));
        return workOrderModelElastic.search(builder);
    }

    /**
     * 获取警告导入详情
     */
    private Iterable<WarningModel> getWarning(String batchNumber) {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", batchNumber));
        return warningModelElastic.search(builder);
    }

    /**
     * 获取留案导入详情
     */
    private Iterable<LeaveCaseModel> getLeave(String batchNumber) {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", batchNumber));
        return leaveCaseModelElastic.search(builder);
    }

    /**
     * 获取停催导入详情
     */
    private Iterable<StopCaseModel> getStop(String batchNumber) {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", batchNumber));
        return stopCaseModelElastic.search(builder);
    }

    /**
     * 待分配案件多条件查询
     */
    public Page<FindDistributeCaseResponse> findDistributeCase(FindDistributeCaseRequest request, Pageable pageable, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        BoolQueryBuilder builder = request.getBuilder();
        baseService.spliceBuilder(builder, userModel);
        FieldSortBuilder sort1 = SortBuilders.fieldSort("delegationDate").unmappedType("long").order(SortOrder.ASC);
        FieldSortBuilder sort2 = SortBuilders.fieldSort("updateTime").unmappedType("long").order(SortOrder.ASC);
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).withSort(sort1).withSort(sort2).build();
        Page<BaseCase> page = baseCaseElastic.search(searchQuery);
        return page.map(e -> modelMapper.map(e, FindDistributeCaseResponse.class));
    }

    /**
     * 生成导入结果
     */
    private DataImportRecord generateRecord(UserModel userModel, String batchNumber, String principalId, String principalName, ImportTemplateType type) {
        DataImportRecord record = new DataImportRecord();
        record.setType(type);
        record.setPrincipalId(principalId);
        record.setPrincipalName(principalName);
        record.setStatus(ImportDataExcelStatus.IMPORTING);
        record.setTotalNumber(0);
        record.setBatchNumber(batchNumber);
        record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
        return dataImportRecordElastic.save(record);
    }

    /**
     * 默认模板ID返回
     */
    public UploadFile getTemplateId(ImportTemplateType type) {
        SysParam sysParam;
        if (Objects.nonNull(type)) {
            switch (type) {
                case BILL_IMPORT:
                    sysParam = sysParamRepository.findOne(QSysParam.sysParam.code.eq("bill_import.template")).orElseThrow(() -> new BadRequestException(null, "sysParam", "sysParam.is.null"));
                    break;
                default:
                    sysParam = null;
                    break;
            }
        } else {
            sysParam = sysParamRepository.findOne(QSysParam.sysParam.code.eq("distribute.template")).orElseThrow(() -> new BadRequestException(null, "sysParam", "sysParam.is.null"));
        }
        if (Objects.nonNull(sysParam)) {
            if (Objects.equals(sysParam.getStatus(), BaseStatus.OFF)) {
                throw new BadRequestException(null, "sysParam", "sysParam.is.off");
            }
            if (StringUtils.isBlank(sysParam.getValue())) {
                throw new BadRequestException(null, "sysParam", "sysParam.value.is.null");
            }
            return baseService.getUploadFile(sysParam.getValue());
        } else {
            throw new BadRequestException(null, "sysParam", "sysParam.is.null");
        }
    }

    /**
     * 公共导入
     */
    public void importCommon(ImportCommonRequest request, String token) throws IOException {
        UserModel userModel = baseService.getUserByToken(token);
        Principal principal = principalRepository.findById(request.getPrincipalId()).orElseThrow(() -> new BadRequestException(null, "principal", "principal.is.null"));
        ImportTemplate importTemplate = importTemplateElastic.findById(request.getTemplateId()).orElseThrow(() -> new BadRequestException(null, "template", "template.is.null"));
        Object o = principalRepository.getBatchNumber();
        String batchNumber = BatchNumberUtil.getBatchNumber(o.toString());
        DataImportRecord result = generateRecord(userModel, batchNumber, principal.getId(), principal.getName(), request.getType());
        InputStream in = baseService.getFile(request.getFileId());
        importCommonTask.processCommonImport(in, importTemplate, result, batchNumber, request.getType(), userModel);
    }

    /**
     * 对账单详情查询
     */
    public Page<PaymentRecordModel> findImportBillByBatchNumber(FindBillRequest request, Pageable pageable) {
        BoolQueryBuilder builder = request.getBuilder();
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).build();
        return paymentRecordModelElastic.search(searchQuery);
    }

    /**
     * 对账单导入确认
     */
    public void confirmImportBill(String id, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        DepartmentModel departmentModel = baseService.getDepartmentByToken(token);
        DataImportRecord record = processRecord(userModel, id, ImportDataExcelStatus.IMPORT_CONFIRMING);
        Iterable<PaymentRecordModel> models = getPaymentRecordModel(record.getBatchNumber());
        //异步执行确认
        confirmBillTask.confirmBill(IterableUtils.toList(models), userModel, record, departmentModel);
    }

    /**
     * 对账单单个撤销
     */
    public void cancelBillImport(String id, String recordId, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        PaymentRecordModel paymentRecordModel = paymentRecordModelElastic.findById(id).orElseThrow(() -> new BadRequestException(null, "paymentRecordModel", "paymentRecordModel.is.null"));
        if (paymentRecordModel.getFlag().equals(1)) {
            throw new BadRequestException(null, "bill", "bill.has.done");
        }
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("caseNumber.keyword", paymentRecordModel.getCaseNumber()));
        Iterable<HistoryCases> iterable = historyCasesRepository.search(builder);
        if (iterable.iterator().hasNext()) {
            throw new BadRequestException(null, "paymentRecord", "case.is.end");
        }
        DataImportRecord dataImportRecord = dataImportRecordElastic.findById(recordId).orElseThrow(() -> new BadRequestException(null, "dataImportRecord", "dataImportRecord.is.null"));
        dataImportRecord.setStatus(ImportDataExcelStatus.REVOKING);
        dataImportRecordElastic.save(dataImportRecord);
        cancelBillTask.processCancelBill(Collections.singletonList(paymentRecordModel), dataImportRecord, paymentRecordModel.getBatchNumber(), userModel, CancelCategory.SINGLE);
    }

    /**
     * 对账单批量撤销
     */
    public void cancelBatchBillImport(String batchNumber, String recordId, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        DataImportRecord dataImportRecord = dataImportRecordElastic.findById(recordId).orElseThrow(() -> new BadRequestException(null, "dataImportRecord", "dataImportRecord.is.null"));
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", batchNumber));
        Iterable<PaymentRecordModel> iterable = paymentRecordModelElastic.search(builder);
        List<PaymentRecordModel> list = IterableUtils.toList(iterable);
        BoolQueryBuilder builder1 = new BoolQueryBuilder();
        List<String> caseNumbers = new ArrayList<>();
        list.forEach(e -> caseNumbers.add(e.getCaseNumber()));
        builder1.must(QueryBuilders.termsQuery("caseNumber.keyword", caseNumbers));
        Iterable<HistoryCases> historyCasesIterable = historyCasesRepository.search(builder1);
        if (historyCasesIterable.iterator().hasNext()) {
            throw new BadRequestException(null, "paymentRecord", "case.is.not.exist");
        }
        dataImportRecord.setStatus(ImportDataExcelStatus.REVOKING);
        dataImportRecordElastic.save(dataImportRecord);
        cancelBillTask.processCancelBill(list, dataImportRecord, batchNumber, userModel, CancelCategory.BATCH);
    }

    /**
     * 委前催记详情查询
     */
    public Page<PreRecordModel> findImportPreByBatchNumber(FindPreRecordRequest request, Pageable pageable) {
        BoolQueryBuilder builder = request.getBuilder();
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).build();
        return preRecordModelElastic.search(searchQuery);
    }

    /**
     * 委前催记导入确认
     */
    public void confirmImportPreRecord(String id, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        DataImportRecord record = processRecord(userModel, id, ImportDataExcelStatus.IMPORT_CONFIRMING);
        Iterable<PreRecordModel> models = getPreRecordModel(record.getBatchNumber());
        //异步执行确认
        confirmPreRecordTask.confirmPreRecord(IterableUtils.toList(models), userModel, record);
    }

    /**
     * 工单详情查询
     */
    public Page<WorkOrderModel> findImportWorkByBatchNumber(FindWorkRequest request, Pageable pageable) {
        BoolQueryBuilder builder = request.getBuilder();
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).build();
        return workOrderModelElastic.search(searchQuery);
    }

    /**
     * 警告详情查询
     */
    public Page<WarningModel> findImportWarningByBatchNumber(FindWarningRequest request, Pageable pageable) {
        BoolQueryBuilder builder = request.getBuilder();
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).build();
        return warningModelElastic.search(searchQuery);
    }

    /**
     * 工单导入确认
     */
    public void confirmImportWorkOrder(String id, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        DataImportRecord record = processRecord(userModel, id, ImportDataExcelStatus.IMPORT_CONFIRMING);
        Iterable<WorkOrderModel> models = getWorkOrder(record.getBatchNumber());
        //异步执行确认
        confirmWorkOrderTask.confirmWorkOrder(IterableUtils.toList(models), userModel, record);
    }

    /**
     * 警告导入确认
     */
    public void confirmImportWarning(String id, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        DataImportRecord record = processRecord(userModel, id, ImportDataExcelStatus.IMPORT_CONFIRMING);
        Iterable<WarningModel> models = getWarning(record.getBatchNumber());
        //异步执行确认
        confirmWarningTask.confirmWarning(IterableUtils.toList(models), userModel, record);
    }

    /**
     * 导入撤销
     */
    public void cancelBatchImport(String id, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        DataImportRecord dataImportRecord = dataImportRecordElastic.findById(id).orElseThrow(() -> new BadRequestException(null, "dataImportRecord", "dataImportRecord.is.null"));
        dataImportRecord.setStatus(REVOKING);
        dataImportRecord.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
        dataImportRecordElastic.save(dataImportRecord);
        ImportTemplateType type = dataImportRecord.getType();
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", dataImportRecord.getBatchNumber()));
        switch (type) {
            case PRE_RECORD_IMPORT:
                cancelPreTask.cancelPre(builder, dataImportRecord, userModel);
                break;
            case WORK_ORDER_IMPORT:
                cancelWorkOrderTask.cancelWorkOrder(builder, dataImportRecord, userModel);
                break;
            case WARNING_IMPORT:
                cancelWarningTask.cancelWarning(builder, dataImportRecord, userModel);
                break;
            case LEAVE_IMPORT:
                cancelLeaveTask.cancelLeave(builder, dataImportRecord, userModel);
                break;
            case STOP_IMPORT:
                cancelStopTask.cancelStop(builder, dataImportRecord, userModel);
                break;
            default:
        }
    }

    /**
     * 留案导入详情查询
     */
    public Page<LeaveCaseModel> findImportLeaveByBatchNumber(FindCommonRequest request, Pageable pageable) {
        BoolQueryBuilder builder = request.getBuilder();
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).build();
        return leaveCaseModelElastic.search(searchQuery);
    }

    /**
     * 停催导入详情查询
     */
    public Page<StopCaseModel> findImportStopByBatchNumber(FindCommonRequest request, Pageable pageable) {
        BoolQueryBuilder builder = request.getBuilder();
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).build();
        return stopCaseModelElastic.search(searchQuery);
    }

    /**
     * 留案导入确认
     */
    public void confirmImportLeave(String id, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        DataImportRecord record = processRecord(userModel, id, ImportDataExcelStatus.IMPORT_CONFIRMING);
        Iterable<LeaveCaseModel> models = getLeave(record.getBatchNumber());
        //异步执行确认
        confirmLeaveTask.confirmLeave(IterableUtils.toList(models), userModel, record);
    }

    /**
     * 停催导入确认
     */
    public void confirmImportStop(String id, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        DataImportRecord record = processRecord(userModel, id, ImportDataExcelStatus.IMPORT_CONFIRMING);
        Iterable<StopCaseModel> models = getStop(record.getBatchNumber());
        //异步执行确认
        confirmStopTask.confirmStop(IterableUtils.toList(models), userModel, record);
    }

    /**
     * 分案导入
     */
    public void importDistribute(String fileId, String token) throws IOException {
        UserModel userModel = baseService.getUserByToken(token);
        Object o = principalRepository.getBatchNumber();
        String batchNumber = BatchNumberUtil.getBatchNumber(o.toString());
        DistributeImportRecord record = new DistributeImportRecord();
        record.setBatchNumber(batchNumber);
        record.setFileId(fileId);
        record.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        record.setStatus(ImportDataExcelStatus.IMPORTING);
        record.setTotalNumber(0);
        record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
        record = distributeImportRecordElastic.save(record);
        InputStream in = baseService.getFile(fileId);
        importDistributeTask.processDistribute(in, record, batchNumber, userModel);
    }

    /**
     * 下载分案导入模板
     */
    public UploadFile downloadDistributeTemplate() throws IOException {
        UploadFile uploadFile;
        try {
            uploadFile = getTemplateId(null);
        } catch (Exception e) {
            throw new BadRequestException(null, "uploadFile", "template.is.overtime");
        }
        InputStream inputStream = baseService.getFile(uploadFile.getId());
        //获取用户集合
        Iterable<User> users = userRepository.findAll(QUser.user.status.in(UserStatus.LOCKING, UserStatus.WORKING));
        List<String> userNames = new ArrayList<>();
        users.forEach(e -> userNames.add(e.getUsername()));
        String[] u = new String[userNames.size()];
        userNames.toArray(u);
        //获取委托方集合
        List<Principal> principals = principalRepository.findAllByStatus(BaseStatus.ON);
        List<String> principalName = new ArrayList<>();
        principals.forEach(e -> principalName.add(e.getName()));
        String[] p = new String[principalName.size()];
        principalName.toArray(p);
        ByteArrayOutputStream byteArrayOutputStream = null;
        FileOutputStream outputStream = null;
        try {
            XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = xssfWorkbook.getSheetAt(0);
            //绑定委托方
            bindSheet(sheet, 1, 10000, 1, 1, p);
            //绑定工号
            bindSheet(sheet, 1, 10000, 7, 7, u);
            String path = "/home/temp/" + ZWDateUtil.fomratterDate(new Date(), "yyyyMMdd") + "分案导入模板" + ".xlsx";
            File file = new File(path);
            byteArrayOutputStream = new ByteArrayOutputStream();
            outputStream = new FileOutputStream(file);
            xssfWorkbook.write(outputStream);
            byteArrayOutputStream.writeTo(outputStream);
            outputStream.flush();
            byteArrayOutputStream.flush();
            return baseService.uploadExcel(file);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BadRequestException(null, "template", "template.is.error");
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
            if (byteArrayOutputStream != null) {
                byteArrayOutputStream.close();
            }
        }
    }

    /**
     * excel绑定下拉框
     */
    private void bindSheet(XSSFSheet sheet, int firstRow, int lastRow, int firstCol, int lastCol, String[] str) {
        XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
        XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint) dvHelper.createExplicitListConstraint(str);
        CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, firstCol, lastCol);
        XSSFDataValidation validation = (XSSFDataValidation) dvHelper.createValidation(dvConstraint, addressList);
        validation.setSuppressDropDownArrow(true);
        validation.setShowErrorBox(true);
        sheet.addValidationData(validation);
    }

    /**
     * 分案导入结果查询
     */
    public Page<DistributeImportRecord> findAllDistributeRecord(FindDistributeRecordRequest request, Pageable
            pageable) {
        BoolQueryBuilder builder = request.getBuilder();
        SortBuilder sortBuilder = SortBuilders.fieldSort("operateTime").unmappedType("long").order(SortOrder.DESC);
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withSort(sortBuilder).withPageable(pageable).build();
        return distributeImportRecordElastic.search(searchQuery);
    }

    /**
     * 分案啊导入取消
     */
    public void cancelImportDistribute(String id, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        DistributeImportRecord record = distributeImportRecordElastic.findById(id).orElseThrow(() -> new BadRequestException(null, "dataImportRecord", "dataImportRecord.is.null"));
        record.setStatus(ImportDataExcelStatus.IMPORT_CANCEL); //导入确认中
        record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
        distributeImportRecordElastic.save(record);
        distributeModelElastic.deleteAllByBatchNumber(record.getBatchNumber());
    }

    /**
     * 分案导入详情查询
     */
    public Page<DistributeModel> findImportDistributeByBatchNumber(String batchNumber, String caseNumber, Pageable
            pageable) {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", batchNumber));
        if (StringUtils.isNotBlank(caseNumber)) {
            builder.must(QueryBuilders.matchPhraseQuery("caseNumber.keyword", caseNumber));
        }
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).build();
        return distributeModelElastic.search(searchQuery);
    }

    /**
     * 分案导入确认
     */
    public void confirmImportDistribute(String id, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        DistributeImportRecord record = distributeImportRecordElastic.findById(id).orElseThrow(() -> new BadRequestException(null, "dataImportRecord", "dataImportRecord.is.null"));
        record.setStatus(ImportDataExcelStatus.IMPORT_CONFIRMING);
        record.process(userModel.getRealName(), ZWDateUtil.getNowDateTime());
        distributeImportRecordElastic.save(record);
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("batchNumber.keyword", record.getBatchNumber()));
        Iterable<DistributeModel> iterable = distributeModelElastic.search(builder);
        //异步执行确认
        confirmDistributeTask.confirmImportDistribute(IterableUtils.toList(iterable), userModel, record);
    }

    public Page<FindDistributeCaseResponse> findSettleCase(SettleCaseRequest settleCaseRequest, Pageable
            pageable, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        BoolQueryBuilder builder = settleCaseRequest.getBuilder();
        baseService.spliceBuilder(builder, userModel);
        FieldSortBuilder sort1 = SortBuilders.fieldSort("delegationDate").unmappedType("long").order(SortOrder.ASC);
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).withSort(sort1).build();
        Page<BaseCase> page = baseCaseElastic.search(searchQuery);
        return page.map(e -> modelMapper.map(e, FindDistributeCaseResponse.class));
    }
}